/*Copyright (c) 2012 Nicolás Zalaquett

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the
Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice
shall be included in all copies or substantial portions of
the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.*/
package extrae;

import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.control.Label;
import javax.swing.JOptionPane;
import java.lang.Exception;
import java.util.Enumeration;
import java.lang.Byte;
import gnu.io.*;
import java.io.InputStream;
import java.io.OutputStream;
import org.jfxtras.stage.XDialog;
import javafx.scene.control.ListView;
import javafx.scene.control.ScrollView;
import javafx.scene.Node;
import javafx.scene.layout.VBox;
import extrae.selectorSensores.sensorNode;
import java.net.URL;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.geometry.HPos;
import javafx.scene.text.TextAlignment;
import javafx.geometry.VPos;
import javafx.scene.control.Tooltip;
import extrae.selectorSensores.sensorNodeAN;
import extrae.Configuraciones.configuracionAnalogos;
import javafx.stage.Stage;
import javafx.scene.shape.Polyline;
import javafx.util.Math;
import javafx.util.Bits;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import extrae.TablaLlegadaDatos.TestData;
import com.javafx.preview.control.TreeItem;
import com.javafx.preview.control.TreeItemBase;
import javafx.fxd.Duplicator;
import java.lang.Object;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.MouseButton;
import extrae.Grafico.GraficoNode;
import javafx.scene.control.CheckBox;
import java.lang.Thread;
import javax.swing.JFileChooser;
import java.io.File;
import extrae.Serializador.Archivo;
import extrae.selectorSensores.sensorAN;
import extrae.selectorSensores.sensorDIG;
import javax.swing.JDialog;
import com.javafx.preview.control.PopupMenu;
import com.javafx.preview.control.MenuItem;
import javafx.scene.control.Separator;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.LayoutInfo;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.geometry.Insets;
import javafx.scene.layout.Priority;
import javafx.scene.control.ScrollBar;

/**
 * @author lojkoro
 */
// <editor-fold defaultstate="collapsed" desc="Variables Globales">
var StagesAN: StageAN[] = [StageAN {}, StageAN {}, StageAN {}];
var StagesDIG: StageDIG[] = [StageDIG {}, StageDIG {}, StageDIG {}, StageDIG {}];
var StagesDIGVel: StageDIG[] = [StageDIG {}, StageDIG {}, StageDIG {}, StageDIG {}];
var recibiendo: Boolean = false;
var counterRecibidosAN: Integer = 0;
var counterRecibidosDIG: Integer[] = [0, 0, 0, 0];
var MedicionesAN: MedicionAnaloga[] = [];
var MedicionesDIG: MedicionDigital[] = [];
var counterVel: Integer[] = [0, 0, 0, 0];
var serializador: Serializador = Serializador {};
// </editor-fold>
public class Main {
    // <editor-fold defaultstate="collapsed" desc="Variables">

    var popupMenu: PopupMenu = PopupMenu {
                items: [
                    MenuItem {
                        text: "Tabla"
                        action: function() {
                        }
                    }
                    Separator {},
                    MenuItem {
                        text: "Gráfico"
                        action: function() {
                        }
                    }
                ]
            };
    public var listenerSocket: ServerSocketListener = ServerSocketListener {};
    public var servidorXML: SocketServer;
    public var servidorXML2: SocketServer;
    public var socketClosed = true;
    public def osciloscopio: Osciloscopio = Osciloscopio {
                layoutY: 100
                layoutX: 0
                pAN: bind paramAN
            };
    public var SensorNeutro: sensorAN = sensorAN {
                nombre: "Entrada Neutra"
                imagen: ""
                unidades: "[-]"
                corte: 0
                pendiente: 1
                resolucion: 1
                rangoMin: 0
                rangoMax: 1023 };
    public var SensorNeutroDIG: sensorDIG = sensorDIG {
                nombre: "Entrada Neutra"
                imagen: ""
                tipoInterrupcion: false
                regleta: 10
            };
    public var canalesAN: canalAnalogo[] = [canalAnalogo { i: 1
                    sensor: bind paramAN.canalSensor[0]
                    botonAux: Button { action: asignadorCanal(0, 0) } },
                canalAnalogo { i: 2
                    sensor: bind paramAN.canalSensor[1]
                    botonAux: Button { action: asignadorCanal(0, 1) } },
                canalAnalogo { i: 3
                    sensor: bind paramAN.canalSensor[2]
                    botonAux: Button { action: asignadorCanal(0, 2) } }];
    public var canalesDIG: canalDigital[] = [canalDigital { i: 1
                    sensor: bind paramDIG.canalSensor[0]
                    botonAux: Button { action: asignadorCanal(1, 0) } },
                canalDigital { i: 2
                    sensor: bind paramDIG.canalSensor[1]
                    botonAux: Button { action: asignadorCanal(1, 1) } },
                canalDigital { i: 3
                    sensor: bind paramDIG.canalSensor[2]
                    botonAux: Button { action: asignadorCanal(1, 2) } },
                canalDigital { i: 4
                    sensor: bind paramDIG.canalSensor[3]
                    botonAux: Button { action: asignadorCanal(1, 3) } }];
    public var paramDIG: parametrosDigital = parametrosDigital {
                canalActivo: bind [canalesDIG[0].checkboxDIG.selected,
                    canalesDIG[1].checkboxDIG.selected,
                    canalesDIG[2].checkboxDIG.selected,
                    canalesDIG[3].checkboxDIG.selected,]
                canalSensor: [SensorNeutroDIG, SensorNeutroDIG, SensorNeutroDIG, SensorNeutroDIG] };
    public var paramAN: parametrosAnalogo = parametrosAnalogo {
                canalActivo: bind [canalesAN[0].checkboxAN.selected,
                    canalesAN[1].checkboxAN.selected,
                    canalesAN[2].checkboxAN.selected]
                valorTasa: 10
                unidadesTasa: 1
                numeroDatos: 100
                cota: 0
                gatillo: 0
                BoS: true
                canalSensor: [SensorNeutro, SensorNeutro, SensorNeutro] };
    public var timingDIG: Integer = 0;
    public var timingAN: Integer = 0;
    public var timingDIGI: Integer[] = [0, 0, 0, 0];
    public var timingANA: Integer[] = [0, 0, 0];
    var puertoSerial: SerialPort;
    var conectado: Boolean = false;
    var timerPooling: Timeline;
    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Imagenes">
    public-read def imageConectar: javafx.scene.image.Image = javafx.scene.image.Image {
                url: "{__DIR__}recursos/Conectar.png"
                width: 113
                preserveRatio: true
            }
    public var imageDesconectar: javafx.scene.image.Image = javafx.scene.image.Image {
                url: "{__DIR__}recursos/Desconectar.png"
                width: 113.0
                preserveRatio: true
            }
    public-read def imagebotADA: javafx.scene.image.Image = javafx.scene.image.Image {
                url: "{__DIR__}recursos/Fwd-analogo.png"
                width: 100
                height: 0.0
                preserveRatio: true
            }
    public-read def imagebotADD: javafx.scene.image.Image = javafx.scene.image.Image {
                url: "{__DIR__}recursos/Fwd-digital.png"
                width: 100
                height: 0.0
                preserveRatio: true
            }
    public var imageViewConectar: javafx.scene.image.Image = bind RecursoConectar;
    public var RecursoConectar: javafx.scene.image.Image = imageConectar;
    public var recursoImagenAD: javafx.scene.image.Image = imagebotADA;
    public-read def imageViewTiempoReal: javafx.scene.image.ImageView = javafx.scene.image.ImageView {
                image: Image {
                    url: "{__DIR__}recursos/matrix.gif"
                    width: 120.0
                    height: 0.0
                    preserveRatio: true }
            }
    public var imageViewLogoInicio: javafx.scene.image.ImageView = javafx.scene.image.ImageView {
                visible: false
                layoutX: 200.0
                layoutY: 5
                fitWidth: 400.0
                fitHeight: 266
                image: Image {
                    url: "{__DIR__}recursos/Logo.png"
                    height: 266
                    preserveRatio: true }
            }
    public var imageViewAD: javafx.scene.image.ImageView = javafx.scene.image.ImageView {
                image: bind recursoImagenAD
            }
    public var imageBotonConectar: javafx.scene.image.ImageView = javafx.scene.image.ImageView {
                image: bind imageViewConectar
            }
    public var imageFondo: javafx.scene.image.ImageView = javafx.scene.image.ImageView {
                visible: true
                disable: false
                opacity: 0.34
                layoutX: 0.0
                layoutY: 0.0
                scaleZ: 1.0
                image: Image {
                    url: "{__DIR__}recursos/Fondo.png"
                    width: 800.0
                    height: 0.0
                    preserveRatio: true
                }
                fitWidth: 800.0
                fitHeight: 600.0
                smooth: true
            }
    public var imageLogo: javafx.scene.image.ImageView = javafx.scene.image.ImageView {
                visible: false
                layoutX: 360
                layoutY: -10.0
                image: Image {
                    url: "{__DIR__}recursos/Logo.png"
                    width: 0.0
                    height: 90.0
                    preserveRatio: true
                }
                fitWidth: 0.0
                fitHeight: 0.0
            }
    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Analogos">
    public var ordenHorizontalAN: HBox = HBox {
                padding: Insets { top: 2 right: 10 bottom: 2 left: 10 }
                spacing: 15
                nodeVPos: VPos.TOP
                layoutInfo: LayoutInfo {
                    hfill: true
                    hgrow: Priority.NEVER hshrink: Priority.NEVER
                }
                content: [canalesAN[0], Separator { height: 254.0 vertical: true },
                    canalesAN[1], Separator { height: 254.0 vertical: true },
                    canalesAN[2],]
            }
    public var panelCanalesAnalogos: javafx.scene.layout.Panel = javafx.scene.layout.Panel {
                visible: false
                disable: false
                layoutX: 230.0
                layoutY: 80.0
                content: [ordenHorizontalAN]
            }
    public var botonTiempoReal: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 20.0
                layoutY: 400.0
                layoutInfo: LayoutInfo { width: 162.0
                    height: 120.0 }
                onMouseEntered: function(event) {
                    botonTiempoReal.effect = dropShadowEffect;
                }
                onMouseExited: function(event) {
                    botonTiempoReal.effect = null;
                }
                onMousePressed: function(event) {
                    botonTiempoReal.effect = innerShadowEffect;
                }
                onMouseReleased: function(event) {
                    botonTiempoReal.effect = dropShadowEffect;
                }
                //graphic: imageViewTiempoReal
                text: "Tiempo Real"
                action: function(): Void {
                    currentState.actual = currentState.findIndex("TiempoReal");
                }
            }
    public var buttonConfigurar: javafx.scene.control.Button = javafx.scene.control.Button {
                vpos: VPos.BOTTOM
                width: 120.0
                height: 20.0
                text: "Configurar"
                font: null
                action: function() {
                    var configurar: configuracionAnalogos = configuracionAnalogos {};
                    configurar.Sensores = paramAN.canalSensor;
                    configurar.canalGatillo = paramAN.gatillo;
                    configurar.cotaGatillo = paramAN.cota;
                    configurar.unidadesMuestra = paramAN.unidadesTasa;
                    configurar.choiceBoxUnidadesTasa.select(configurar.unidadesMuestra);
                    configurar.numeroMuestras = paramAN.numeroDatos;
                    configurar.sobreobajo = paramAN.BoS;
                    configurar.valorTasa = paramAN.valorTasa;
                    configurar.textBoxNumeroMuestras.text = "{paramAN.numeroDatos}";
                    configurar.sliderGatilloCota.value = paramAN.cota;
                    //configurar.textBoxGatilloCota.text="{configurar.obtenerCotaNumero(paramAN.cota,paramAN.canalSensor[paramAN.gatillo])}";
                    configurar.textBoxValorTasa.text = "{paramAN.valorTasa}";
                    configurar.radioButtonGatillo1.disable = not paramAN.canalActivo[0];
                    configurar.radioButtonGatillo2.disable = not paramAN.canalActivo[1];
                    configurar.radioButtonGatillo3.disable = not paramAN.canalActivo[2];
                    configurar.buttonGuardarConfiguracion.action = function(): Void {
                                configurar.guardar = true;
                                configurar.buttonCancelar.scene.stage.close();
                            };
                    configurar.buttonCancelar.action = function(): Void {
                                configurar.buttonCancelar.scene.stage.close();
                            };
                    var heightConf = 340;
                    if (botonGuardarSerie.visible) {
                        heightConf = 150;
                        configurar.textBoxNumeroMuestras.visible = false;
                        configurar.separator.visible = false;
                        configurar.separator2.visible = false;
                        configurar.panel2.visible = false;
                        configurar.panel3.visible = false;
                        configurar.buttonCancelar.layoutY = 80;
                        configurar.buttonGuardarConfiguracion.layoutY = 80;
                    }
                    var dialogo2: XDialog = XDialog {
                                title: "Configuración Avanzada"
                                resizable: false
                                modal: false
                                scene: Scene {
                                    width: 230
                                    height: heightConf
                                    content: configurar }
                                onClose: function(): Void {
                                    if (configurar.guardar) {
                                        paramAN.gatillo = configurar.canalGatillo;
                                        paramAN.cota = configurar.cotaGatillo;
                                        paramAN.unidadesTasa = configurar.unidadesMuestra;
                                        paramAN.numeroDatos = configurar.numeroMuestras;
                                        paramAN.BoS = configurar.sobreobajo;
                                        paramAN.valorTasa = configurar.valorTasa; }
                                } };

                }
            }
    public var labelParametros: javafx.scene.control.Label = javafx.scene.control.Label {
                layoutInfo: LayoutInfo { width: 120.0
                    height: 20.0 }
                text: "Par\u00E1metros :"
                hpos: javafx.geometry.HPos.CENTER
                textFill: javafx.scene.paint.Color.BLACK
            }
    public var labelIntervaloInfo: javafx.scene.control.Label = javafx.scene.control.Label {
                layoutInfo: LayoutInfo { width: 120.0 }
                text: "Intervalo"
                textAlignment: javafx.scene.text.TextAlignment.CENTER
                hpos: javafx.geometry.HPos.CENTER
            }
    public var labelNumeroDatosTitulo: javafx.scene.control.Label = javafx.scene.control.Label {
                layoutInfo: LayoutInfo { width: 120.0 }
                text: "Numero de Datos"
                hpos: javafx.geometry.HPos.CENTER
            }
    public var labelNumeroDatosInfo: javafx.scene.control.Label = javafx.scene.control.Label {
                layoutInfo: LayoutInfo { width: 120.0 }
                text: bind "{paramAN.numeroDatos}"
                hpos: javafx.geometry.HPos.CENTER
                textFill: Color { red: 0.8 }
            }
    public var labelIntervalo: javafx.scene.control.Label = javafx.scene.control.Label {
                layoutInfo: LayoutInfo { width: 120.0 }
                styleClass: ""
                text: bind "{paramAN.valorTasa} {unidadesPalabra(paramAN.unidadesTasa)}"
                hpos: javafx.geometry.HPos.CENTER
                textFill: Color { red: 0.8 }
            }
    public var ordenVerticalInfoMedicion: VBox = VBox {
                padding: Insets { top: 0 right: 0 bottom: 0 left: 0 }
                spacing: 13
                vpos: VPos.TOP
                nodeHPos: HPos.CENTER
                content: [labelParametros, Separator { width: 120.0 }, labelIntervaloInfo,
                    labelIntervalo, Separator { width: 120.0 }, labelNumeroDatosTitulo,
                    labelNumeroDatosInfo, buttonConfigurar]
            }
    public var panelInfoMedicion: javafx.scene.layout.Panel = javafx.scene.layout.Panel {
                visible: false
                disable: false
                layoutX: 635.0
                layoutY: 100.0
                /*layoutInfo: LayoutInfo{width: 0.0
                height: 0.0}*/
                effect: null
                content: [ordenVerticalInfoMedicion]
            }
    public var botonGuardarSerie: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 640.0
                layoutY: 379.0
                layoutInfo: LayoutInfo { width: 113.0
                    height: 77.0 }
                text: "Guardar Serie"
                action: function(): Void {
                    var me: MedicionAnaloga = MedicionAnaloga {
                                timing: timingAN
                                Datos: osciloscopio.datos
                            }
                    me.parametros.clonar(paramAN);
                    me.parametros.numeroDatos = osciloscopio.numeroDatos;
                    insert me into MedicionesAN;
                    timingAN++;
                    childrenAN1 = createChildrenAN(0);
                    childrenAN2 = createChildrenAN(1);
                    childrenAN3 = createChildrenAN(2);
                    JOptionPane.showMessageDialog(null, "Medición guardada", "Medicion guardada", JOptionPane.OK_OPTION);
                }
            }
    public var checkBoxFlash: CheckBox = CheckBox {
                layoutX: 640.0
                layoutY: 340.0
                text: "Conectar con Flash"
                visible: false
            }
    public var progressbar: javafx.scene.control.ProgressBar = javafx.scene.control.ProgressBar {
                visible: false
                layoutX: 640.0
                layoutY: 550.0
                layoutInfo: LayoutInfo { width: 113.0
                    height: 12.0 }
                progress: bind if (recibiendo and counterRecibidosAN > 0) { (((counterRecibidosAN + 1) as Number) / paramAN.numeroDatos  as Number) } else { 0 }
            }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Inicio">
    public var botonInicioAnalogos: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 150.0
                layoutY: 400.0
                layoutInfo: LayoutInfo { width: 150.0
                    height: 100.0 }
                effect: null
                text: "An\u00E1logos"
                font: null
            }
    public var botonInicioDigitales: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 500.0
                layoutY: 400.0
                layoutInfo: LayoutInfo { width: 150.0
                    height: 100.0 }
                text: "Digitales"
            }
    public var labelBienvenido: javafx.scene.control.Label = javafx.scene.control.Label {
                visible: false
                layoutX: 200.0
                layoutY: 150.0
                layoutInfo: LayoutInfo { width: 403.0
                    height: 109.0 }
                effect: null
                text: "Bienvenido a la Interfaz de Usuario"
                font: Font { size: 25.0 }
                textAlignment: javafx.scene.text.TextAlignment.CENTER
                hpos: javafx.geometry.HPos.CENTER
            }
    public var labelQueTipoUsar: javafx.scene.control.Label = javafx.scene.control.Label {
                visible: false
                layoutX: 150.0
                layoutY: 225.0
                layoutInfo: LayoutInfo { width: 490.0
                    height: 131.0 }
                text: "\u00BFQue tipo de sensor usar\u00E1s hoy?"
                font: Font { size: 15.0 }
                hpos: javafx.geometry.HPos.CENTER
            }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Digitales">
    public var ordenHorizontalDIG: HBox = HBox {
                padding: Insets { top: 2 right: 10 bottom: 2 left: 10 }
                spacing: 15
                nodeVPos: VPos.TOP
                layoutInfo: LayoutInfo {
                    hfill: true
                    hgrow: Priority.NEVER hshrink: Priority.NEVER
                }
                content: [canalesDIG[0], Separator { height: 254.0 vertical: true },
                    canalesDIG[1], Separator { height: 254.0 vertical: true },
                    canalesDIG[2], Separator { height: 254.0 vertical: true },
                    canalesDIG[3],]
            }
    public var panelCanalesDigitales: javafx.scene.layout.Panel = javafx.scene.layout.Panel {
                visible: false
                disable: true
                layoutX: 250
                layoutY: 75.0
                layoutInfo: LayoutInfo { width: 0.0 }
                content: [ordenHorizontalDIG]
            }
    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="TreeViewDatos y TextBoxNotas">
    public var treeViewDatos: com.javafx.preview.control.TreeView = com.javafx.preview.control.TreeView {
                visible: false
                layoutX: 20.0
                layoutY: 100.0
                onMouseEntered: function(event) {
                    treeViewDatos.effect = dropShadowEffect;
                }
                onMouseExited: function(event) {
                    treeViewDatos.effect = null;
                }
                effect: null
                root: TreeItem {
                    data: "Series"
                    children: [TreeItem { data: "Analogo" children: [
                                TreeItem { data: "AN1" children: bind childrenAN1 },
                                TreeItem { data: "AN2" children: bind childrenAN2 },
                                TreeItem { data: "AN3" children: bind childrenAN3 },] },
                        TreeItem { data: "Digital" children: [
                                TreeItem { data: "DIG1" children: bind childrenDIG1 },
                                TreeItem { data: "DIG2" children: bind childrenDIG2 },
                                TreeItem { data: "DIG3" children: bind childrenDIG3 },
                                TreeItem { data: "DIG4" children: bind childrenDIG4 },] }]
                }
                onMouseClicked: function(e: MouseEvent) {
                    if (treeViewDatos.selectedItem.level == 4) {
                        popupMenu.hide();
                        var dataText = treeViewDatos.selectedItem.parent.data;
                        if (dataText == "AN1" or dataText == "AN2" or dataText == "AN3") {
                            var serie: String = treeViewDatos.selectedItem.data.toString();
                            var letra: String;
                            if("{serie.charAt(7)}"!=" "){
                                if("{serie.charAt(8)}"!=" "){
                                    letra= "{serie.charAt(6)}{serie.charAt(7)}{serie.charAt(8)}";}
                                else{
                                    letra= "{serie.charAt(6)}{serie.charAt(7)}";}}
                            else{
                                letra= "{serie.charAt(6)}";}
                            var i: Integer = Integer.parseInt(letra);
                            var j: Integer;
                            if (dataText == "AN1") {
                                j = 0; }
                            if (dataText == "AN2") {
                                j = 1; }
                            if (dataText == "AN3") {
                                j = 2; };
                            (popupMenu.items[2] as MenuItem).action = function(): Void {
                                        graficar(i, j, 0)
                                    };
                            (popupMenu.items[0] as MenuItem).action = function(): Void {
                                        generarTabla(i,j,0);
                                    };
                            popupMenu.show(treeViewDatos, e.screenX, e.screenY);
                        }
                        else if (dataText == "DIG1" or dataText == "DIG2" or dataText == "DIG3" or dataText == "DIG4") {
                            var serie: String = treeViewDatos.selectedItem.data.toString();
                            var letra: String;
                            if("{serie.charAt(7)}"!=" "){
                                if("{serie.charAt(8)}"!=" "){
                                    letra= "{serie.charAt(6)}{serie.charAt(7)}{serie.charAt(8)}";}
                                else{
                                    letra= "{serie.charAt(6)}{serie.charAt(7)}";}}
                            else{
                                letra= "{serie.charAt(6)}";}
                            var i: Integer = Integer.parseInt(letra);
                            var j: Integer;
                            if (dataText == "DIG1") {
                                j = 0; }
                            else if (dataText == "DIG2") {
                                j = 1; }
                            else if (dataText == "DIG3") {
                                j = 2; }
                            else if (dataText == "DIG4") {j = 3; };
                            (popupMenu.items[2] as MenuItem).action = function(): Void {
                                        graficar(i, j, 1)
                                    };
                            (popupMenu.items[0] as MenuItem).action = function(): Void {
                                        generarTabla(i,j,1);
                                    };
                            popupMenu.show(treeViewDatos, e.screenX, e.screenY);
                        }
                    }
                }
            }
    var childrenAN1: TreeItemBase[] = [];
    var childrenAN2: TreeItemBase[] = [];
    var childrenAN3: TreeItemBase[] = [];
    var childrenDIG1: TreeItemBase[] = [];
    var childrenDIG2: TreeItemBase[] = [];
    var childrenDIG3: TreeItemBase[] = [];
    var childrenDIG4: TreeItemBase[] = [];
    function createChildrenAN(i: Integer): TreeItemBase[] {
        return for (f in MedicionesAN) {
                    if (f.parametros.canalActivo[i]) {
                        TreeItem {
                            data: "Serie {f.timing} - {f.parametros.canalSensor[i].nombre}"
                            children: []
                        }
                    } else [];

                };
    }
    function createChildrenDIG(i: Integer): TreeItemBase[] {
        return for (f in MedicionesDIG) {
                    if (f.parametros.canalActivo[i]) {
                        TreeItem {
                            data: "Serie {f.timing} - {f.parametros.canalSensor[i].nombre}"
                            children: []
                        }
                    } else [];

                }
    }
    public var textboxNotas: javafx.scene.control.TextBox = javafx.scene.control.TextBox {
                visible: false
                layoutX: 230.0
                layoutY: 360.0
                layoutInfo: LayoutInfo { width: 373.0
                    height: 206.0 }
                style: "-fx-background-color: #FEE892;"
                effect: null
                text: "Anota ac\u00E1 lo que necesites recordar de tu experimento..."
                multiline: true
                lines: 100.0
            }
    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Botones Comunes">

    public var buttonAnalogoDigital: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 690
                layoutY: 15
                styleClass: "button1"
                layoutInfo: LayoutInfo { width: 115.0
                    height: 40.0 }
                text: "An\u00E1logos"
                onMouseEntered: function(event) {
                    buttonAnalogoDigital.effect = dropShadowEffect;
                }
                onMouseExited: function(event) {
                    buttonAnalogoDigital.effect = null;
                }
                onMousePressed: function(event) {
                    buttonAnalogoDigital.effect = innerShadowEffect;
                }
                onMouseReleased: function(event) {
                    buttonAnalogoDigital.effect = dropShadowEffect;
                }
                graphic: imageViewAD
            }
    public var botonConectar: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 640.0
                layoutY: 386.0
                layoutInfo: LayoutInfo { width: 113.0
                    height: 74.0 }
                styleClass: "button1"
                onMouseEntered: function(event) {
                    botonConectar.effect = dropShadowEffect;
                }
                onMouseExited: function(event) {
                    botonConectar.effect = null;
                }
                onMousePressed: function(event) {
                    botonConectar.effect = innerShadowEffect;
                }
                onMouseReleased: function(event) {
                    botonConectar.effect = dropShadowEffect;
                }
                graphic: imageBotonConectar
                text: ""
                action: botonConectarAction
            }
    public var botonPlay: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 640.0
                layoutY: 466.0
                layoutInfo: LayoutInfo { width: 113.0
                    height: 77.0 }
                text: "Comenzar"
                disable: bind not conectado
                action: function(): Void {
                    var input: InputStream = puertoSerial.getInputStream();
                    var flushout: Byte[];
                    input.read(flushout);
                    if (recibiendo) {
                        var menviar: Byte[] = [-127, 0, 0, 0, 0, 0, 0, 0, 0, 0];
                        timerPooling.stop();
                        var out: OutputStream = puertoSerial.getOutputStream();
                        out.write(menviar, 0, 10);
                        botonPlay.text = "Comenzar";
                        recibiendo = false;
                        counterRecibidosAN = 0;
                        //if(servidorXML.socketConnection==null){
                        servidorXML.shutdown();
                        socketClosed = true;
                    //}

                    } else {
                        var mandar: Boolean = true;
                        if (panelCanalesAnalogos.visible and (not osciloscopio.visible))
                        {
                            var menviar: Byte[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
                            /*''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                            'Descripcion de bytes en mensaje:
                            '0 : Que operacion Realizar (En este caso fijo en 2 - Sampleo)
                            '1 : Que puertos Samplear
                            '2 : Unidad de tasa de sampleo
                            '3 : Byte "grande" del valor de tasa
                            '4 : Byte "chico" del valor de tasa
                            '5 : Numero de Repeticiones
                            '6 : 3 bit Puerto - 1 bit 0 - 4 bit "grandes" de Cota
                            '7 : 6 bit "chicos" de cota - 1 bit 0 - 1 Bit Bajo o Sobre
                            '8 y 9 : Numero de Datos
                            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''*/
                            menviar[0] = 2;
                            for (i in [0..2]) {
                                if (paramAN.canalActivo[i]) {
                                    menviar[1] += Math.pow(2, i);
                                }
                            }
                            if (menviar[1] == 0) { mandar = false; }//ACA DETENER SI NO HAY CANALES ACTIVOS
                            menviar[2] = Math.pow(2, paramAN.unidadesTasa);
                            menviar[3] = Bits.bitAnd(Bits.shiftRight(paramAN.valorTasa, 8), 255);
                            menviar[4] = Bits.bitAnd(paramAN.valorTasa, 255);
                            menviar[5] = 1; ////ACA VAN LAS REPETICIONES
                            menviar[6] = Math.pow(2, (5 + paramAN.gatillo));
                            menviar[6] += Bits.bitAnd(Bits.shiftRight(paramAN.cota, 6), 15);
                            menviar[7] = Bits.bitAnd(Bits.shiftLeft(paramAN.cota, 2), 252);
                            if (paramAN.BoS) { menviar[7] += 1; }
                            menviar[8] = Bits.bitAnd(Bits.shiftRight(paramAN.numeroDatos, 8), 255);
                            menviar[9] = Bits.bitAnd(paramAN.numeroDatos, 255);
                            /*JOptionPane.showMessageDialog(null, "[0]:{Byte.valueOf(menviar[0])}\n[1]:{menviar[1]}\n[2]:{menviar[2]}\n[3]:{menviar[3]}\n[4]:{menviar[4]}\n[5]:{menviar[5]}\n[6]:{menviar[6]}\n[7]:{menviar[7]}\n[8]:{menviar[8]}\n[9]:{menviar[9]}",
                            "Mensaje : ", JOptionPane.INFORMATION_MESSAGE);*/
                            if (mandar) {
                                //menviar=[2,1,2,0,5,1,32,1,0,100];//PRUEBA
                                for (i in [0..2]) {
                                    if (paramAN.canalActivo[i]) {
                                        insert Stage {
                                            title: "Datos Canal {i + 1} - Serie {timingAN}"
                                            x:250*i
                                            y:0
                                            scene: Scene {
                                                width: 250
                                                height: 300
                                                content: [TablaLlegadaDatos {
                                                        nombreX: unidadesPalabra(paramAN.unidadesTasa)
                                                        nombreY: paramAN.canalSensor[i].unidades },] }
                                        } into StagesAN[i].StageANTabla;
                                        insert Stage {
                                            x:300*i
                                            y:300
                                            title: "Datos Canal {i + 1} - Serie {timingAN}"
                                            scene: Scene {
                                                width: 600
                                                height: 400
                                                content: [GraficoLlegadaDatos {
                                                        MinYv: paramAN.canalSensor[i].rangoMin
                                                        MaxYv: paramAN.canalSensor[i].rangoMax
                                                        MinXv: 0
                                                        MaxXv: paramAN.valorTasa * paramAN.numeroDatos
                                                        UnidadesYv: paramAN.canalSensor[i].unidades
                                                        UnidadesXv: unidadesPalabra(paramAN.unidadesTasa)
                                                    },] }
                                        } into StagesAN[i].StageANGrafico;
                                        timingANA[i]++;
                                    }
                                }
                                var MedAux: MedicionAnaloga = MedicionAnaloga { timing: timingAN };
                                MedAux.parametros.clonar(paramAN);
                                insert MedAux into MedicionesAN;
                                botonPlay.text = "Detener";
                                timerPooling = Timeline {
                                            repeatCount: Timeline.INDEFINITE
                                            keyFrames: [
                                                KeyFrame {
                                                    time: 30ms
                                                    action: poolserial
                                                }
                                            ]
                                        };
                                recibiendo = true;
                                timingAN++;
                                childrenAN1 = createChildrenAN(0);
                                childrenAN2 = createChildrenAN(1);
                                childrenAN3 = createChildrenAN(2);
                                var out: OutputStream = puertoSerial.getOutputStream();
                                out.write(menviar, 0, 10);
                                timerPooling.play();
                            }
                            else {
                                JOptionPane.showMessageDialog(null, "Al menos un sensor debe estar activado.",
                                "No se puede iniciar la medición.", JOptionPane.INFORMATION_MESSAGE);
                            }

                        }
                        else if (osciloscopio.visible) {
                            var menviar: Byte[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
                            /*''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                            'Descripcion de bytes en mensaje:
                            '0 : Que operacion Realizar (En este caso fijo en 2 - Sampleo pero "eterno")
                            '1 : Que puertos Samplear
                            '2 : Unidad de tasa de sampleo
                            '3 : Byte "grande" del valor de tasa
                            '4 : Byte "chico" del valor de tasa
                            '5 : Numero de Repeticiones
                            '6 : 3 bit Puerto - 1 bit 0 - 4 bit "grandes" de Cota
                            '7 : 6 bit "chicos" de cota - 1 bit 0 - 1 Bit Bajo o Sobre
                            '8 y 9 : Numero de Datos
                            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''*/
                            menviar[0] = 2;
                            for (i in [0..2]) {
                                if (paramAN.canalActivo[i]) {
                                    menviar[1] += Math.pow(2, i);
                                }
                            }
                            if (menviar[1] == 0) { mandar = false; }//ACA DETENER SI NO HAY CANALES ACTIVOS
                            menviar[2] = Math.pow(2, paramAN.unidadesTasa);
                            menviar[3] = Bits.bitAnd(Bits.shiftRight(paramAN.valorTasa, 8), 255);
                            menviar[4] = Bits.bitAnd(paramAN.valorTasa, 255);
                            menviar[5] = 1; ////ACA VAN LAS REPETICIONES
                            menviar[6] = Math.pow(2, (5 + paramAN.gatillo));
                            menviar[6] += Bits.bitAnd(Bits.shiftRight(paramAN.cota, 6), 15);
                            menviar[7] = Bits.bitAnd(Bits.shiftLeft(paramAN.cota, 2), 252);
                            if (paramAN.BoS) { menviar[7] += 1; }
                            menviar[8] = 0;
                            menviar[9] = 0;
                            if (mandar) {
                                for (i in [0..2]) {
                                    if (paramAN.canalActivo[i]) {
                                    ///Aca cambiar info del osciloscopio
                                    }
                                }
                                botonPlay.text = "Detener";
                                timerPooling = Timeline {
                                            repeatCount: Timeline.INDEFINITE
                                            keyFrames: [
                                                KeyFrame {
                                                    time: 30ms
                                                    action: poolserialOsciloscopio
                                                }
                                            ]
                                        };
                                recibiendo = true;
                                if (checkBoxFlash.selected and socketClosed) {
                                    try {
                                        servidorXML = new SocketServer(ServerSocketListener {},
                                                8080,
                                                javafx.util.Bits.bitOr(GenericSocket.DEBUG_STATUS,
                                                GenericSocket.DEBUG_IO));
                                        servidorXML2 = new SocketServer(ServerSocketListener {},
                                                4444,
                                                javafx.util.Bits.bitOr(GenericSocket.DEBUG_STATUS,
                                                GenericSocket.DEBUG_IO));
                                        servidorXML2.policy = true;
                                        servidorXML2.connect();
                                        servidorXML.connect();
                                        socketClosed = false;
                                    } catch (e: Exception) {

                                    }

                                }

                                var out: OutputStream = puertoSerial.getOutputStream();
                                out.write(menviar, 0, 10);
                                timerPooling.play();
                            } else {
                                JOptionPane.showMessageDialog(null, "Al menos un sensor debe estar activado.",
                                "No se puede iniciar la medición.", JOptionPane.INFORMATION_MESSAGE);
                            }

                        }
                        else {
                            var menviar: Byte[] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
                            /*''''''''''''''''''''''''''''''''''''''''''''''''''''''''
                            'Descripcion de bytes en mensaje:
                            '0 : Que operacion Realizar (En este caso fijo en 1 - Digital)
                            '1 : Activa la interrupcion para puertos 1 - 2
                            '2 : Selecciona el formato de interrupcion 1 y 2
                            '3 : Activa interrupcion en canales 3 y 4
                            '4 : Fromato de interrupcion canales 3 y 4
                            '5 : 0
                            '6 : 0
                            '7 : 0
                            '8 y 9 : 0
                            ''''''''''''''''''''''''''''''''''''''''''''''''''''''''*/
                            menviar[0] = 1;
                            for (i in [0..1]) {
                                if (paramDIG.canalActivo[i]) {
                                    menviar[1] += Math.pow(2, i);
                                }
                            }
                            for (i in [0..1]) {
                                if (paramDIG.canalActivo[i]) {
                                    if (paramDIG.canalSensor[i].tipoInterrupcion) {
                                        menviar[2] += 3 * Math.pow(4, i);
                                    } else {
                                        menviar[2] += Math.pow(4, i);
                                    }
                                }
                            }
                            for (i in [2..3]) {
                                if (paramDIG.canalActivo[i]) {
                                    menviar[3] += Math.pow(2, (i - 2));
                                }

                            }
                            for (i in [2..3]) { ///F-T-F-T
                                if (paramDIG.canalActivo[i]) {
                                    if (paramDIG.canalSensor[i].tipoInterrupcion) {
                                        menviar[4] += Math.pow(2, (2 * i - 4));
                                    } else {
                                        menviar[4] += Math.pow(2, (2 * i - 3));
                                    }
                                }

                            }
                            ////Canales 3 y 4 en espera//
                            if (menviar[1] == 0 and menviar[3] == 0) { mandar = false; }//ACA DETENER SI NO HAY CANALES ACTIVOS
                            if (mandar) {
                                for (i in [0..3]) {
                                    counterRecibidosDIG[i] = 0;
                                    counterVel[i] = 0;
                                    if (paramDIG.canalActivo[i]) {
                                        insert Stage {
                                            title: "Datos Canal {i + 1} - Serie {timingDIG}"
                                            x:200*i
                                            y:0
                                            scene: Scene {
                                                width: 200
                                                height: 350
                                                content: [TablaLlegadaDatos {
                                                        nombreX: "Número de evento"
                                                        nombreY: "Tiempo de evento [s]" },] }
                                        } into StagesDIG[i].StageDIGTabla;
                                        insert Stage {
                                            title: "Datos Canal {i + 1} - Serie {timingDIG}"
                                            x:200*i
                                            y:350
                                            scene: Scene {
                                                width: 200
                                                height: 350
                                                content: [TablaLlegadaDatos {
                                                        nombreX: "Velocidad [m/s]"
                                                        nombreY: "Tiempo [s]" },] }
                                        } into StagesDIGVel[i].StageDIGTabla;
                                        /*insert Stage {
                                        title: "Datos Canal {i + 1} - Serie {timingAN}"
                                        scene: Scene {
                                        width: 600
                                        height: 400
                                        content: [GraficoLlegadaDatos {
                                        MinYv: paramAN.canalSensor[i].rangoMin
                                        MaxYv: paramAN.canalSensor[i].rangoMax
                                        MinXv: 0
                                        MaxXv: paramAN.valorTasa * paramAN.numeroDatos
                                        UnidadesYv: paramAN.canalSensor[i].unidades
                                        UnidadesXv: unidadesPalabra(paramAN.unidadesTasa)
                                        },] }
                                        } into StagesAN[i].StageANGrafico;*/
                                        timingDIGI[i]++;
                                    }
                                }
                                var MedAux: MedicionDigital = MedicionDigital { timing: timingDIG
                                            parametros: parametrosDigital {
                                                canalActivo: paramDIG.canalActivo
                                                canalSensor: paramDIG.canalSensor } };
                                insert MedAux into MedicionesDIG;
                                botonPlay.text = "Detener";
                                timerPooling = Timeline {
                                            repeatCount: Timeline.INDEFINITE
                                            keyFrames: [
                                                KeyFrame {
                                                    time: 30ms
                                                    action: poolserialDigital
                                                }
                                            ]
                                        }
                                recibiendo = true;
                                timingDIG++;
                                ///Esto es para llenar el treeview
                                childrenDIG1 = createChildrenDIG(0);
                                childrenDIG2 = createChildrenDIG(1);
                                childrenDIG3 = createChildrenDIG(2);
                                childrenDIG4 = createChildrenDIG(3);
                                var out: OutputStream = puertoSerial.getOutputStream();
                                out.write(menviar, 0, 10);
                                timerPooling.play();
                            } else {
                                JOptionPane.showMessageDialog(null, "Al menos un sensor debe estar activado.",
                                "No se puede iniciar la medición.", JOptionPane.INFORMATION_MESSAGE);
                            }
                        }
                    }
                }
            }
    public var botonEmergencia: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 667.0
                layoutY: 570.0
                text: "Restart"
                action: function(): Void {
                    puertoSerial.setDTR(true);
                    puertoSerial.setDTR(false);
                }
            }
    public var botonAbrir: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 20.0
                layoutY: 15.0
                layoutInfo: LayoutInfo { width: 60.0
                    height: 40.0 }
                style: ""
                styleClass: "button1"
                onMouseEntered: function(event) {
                    botonAbrir.effect = dropShadowEffect;
                }
                onMouseExited: function(event) {
                    botonAbrir.effect = null;
                }
                onMousePressed: function(event) {
                    botonAbrir.effect = innerShadowEffect;
                }
                onMouseReleased: function(event) {
                    botonAbrir.effect = dropShadowEffect;
                }
                graphic: ImageView { layoutInfo: LayoutInfo { hfill: true
                        vfill: true }
                    image: Image { url: "{__DIR__}recursos/Open.png"
                        backgroundLoading: false
                        width: 60.0
                        height: 0.0
                        preserveRatio: true } }
                text: ""
                graphicHPos: javafx.geometry.HPos.CENTER
                graphicVPos: javafx.geometry.VPos.CENTER
                action: function() {
                    var returnVal: Integer;
                    var bb: JFileChooser = new JFileChooser();
                    returnVal = bb.showOpenDialog(null);
                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        var resultado: Integer = JOptionPane.showConfirmDialog(null, "Desea guardar la experiencia que estaba realizando?", "Guardar?", JOptionPane.YES_NO_CANCEL_OPTION);
                        if (resultado == JOptionPane.YES_OPTION) {
                            botonGuardar.action();
                            var file: File = bb.getSelectedFile();
                            var arc: Archivo = serializador.Deserializar(file);
                            MedicionesAN = [];
                            for (m in arc.MedicionesAN) { insert m into MedicionesAN }
                            MedicionesDIG = [];
                            for (m in arc.MedicionesDIG) { insert m into MedicionesDIG }
                            paramAN.clonar2(arc.paramAN);
                            paramDIG.clonar2(arc.paramDIG);
                            timingAN = arc.timingAN;
                            timingDIG = arc.timingDIG;
                            textboxNotas.text = arc.notas;
                            childrenAN1 = createChildrenAN(0);
                            childrenAN2 = createChildrenAN(1);
                            childrenAN3 = createChildrenAN(2);
                            childrenDIG1 = createChildrenDIG(0);
                            childrenDIG2 = createChildrenDIG(1);
                            childrenDIG3 = createChildrenDIG(2);
                            childrenDIG4 = createChildrenDIG(3);
                        } else if (resultado == JOptionPane.CANCEL_OPTION) {
                        } else {

                            var file: File = bb.getSelectedFile();
                            var arc: Archivo = serializador.Deserializar(file);
                            MedicionesAN = [];
                            for (m in arc.MedicionesAN) { insert m into MedicionesAN }
                            MedicionesDIG = [];
                            for (m in arc.MedicionesDIG) { insert m into MedicionesDIG }
                            paramAN.clonar2(arc.paramAN);
                            paramDIG.clonar2(arc.paramDIG);
                            timingAN = arc.timingAN;
                            timingDIG = arc.timingDIG;
                            textboxNotas.text = arc.notas;
                            childrenAN1 = createChildrenAN(0);
                            childrenAN2 = createChildrenAN(1);
                            childrenAN3 = createChildrenAN(2);
                            childrenDIG1 = createChildrenDIG(0);
                            childrenDIG2 = createChildrenDIG(1);
                            childrenDIG3 = createChildrenDIG(2);
                            childrenDIG4 = createChildrenDIG(3);
                        }
                    }
                }
            }
    public var botonGuardar: javafx.scene.control.Button = javafx.scene.control.Button {
                visible: false
                layoutX: 95.0
                layoutY: 15.0
                layoutInfo: LayoutInfo { width: 60.0
                    height: 40.0 }
                styleClass: "button1"
                onMouseEntered: function(event) {
                    botonGuardar.effect = dropShadowEffect;
                }
                onMouseExited: function(event) {
                    botonGuardar.effect = null;
                }
                onMousePressed: function(event) {
                    botonGuardar.effect = innerShadowEffect;
                }
                onMouseReleased: function(event) {
                    botonGuardar.effect = dropShadowEffect;
                }
                graphic: ImageView { image: Image { url: "{__DIR__}recursos/Save.png"
                        width: 50.0
                        height: 0.0
                        preserveRatio: true } }
                text: ""
                action: function() {
                    var returnVal: Integer;
                    var bb: JFileChooser = new JFileChooser();
                    returnVal = bb.showSaveDialog(null);
                    if (returnVal == JFileChooser.APPROVE_OPTION) {
                        var file: File = bb.getSelectedFile();
                        if (file.exists()) {
                            var resultado: Integer = JOptionPane.showConfirmDialog(null, "Se reescribirá el archivo", "Desea reescribir el archivo?", JOptionPane.OK_CANCEL_OPTION);
                            if (resultado == JOptionPane.OK_OPTION) {
                                serializador.generarArchivo(MedicionesAN, MedicionesDIG, paramAN, paramDIG, timingAN, timingDIG, file, textboxNotas.text);
                            } else {
                                botonGuardar.action();
                            }
                        }
                        else {
                            serializador.generarArchivo(MedicionesAN, MedicionesDIG, paramAN, paramDIG, timingAN, timingDIG, file, textboxNotas.text);
                        }
                    }

                }
            }

    function botonConectarAction(): Void {

        if (conectado) {
            puertoSerial.close();
            conectado = false;
            RecursoConectar = imageConectar;
        } else {
            var hayinterfaz: Boolean = false;
            var menviar: Byte[] = [8, 0, 0, 0, 0, 0, 0, 0, 0, 0];
            var llegado: Integer;
            try {
                var puertos: Enumeration = CommPortIdentifier.getPortIdentifiers();
                while (puertos.hasMoreElements() and (not hayinterfaz)) {
                    var puerto: CommPortIdentifier = puertos.nextElement() as CommPortIdentifier;
                    var puertoAux: SerialPort;
                    if (puerto.getPortType() == CommPortIdentifier.PORT_SERIAL) {
                        if (not puerto.isCurrentlyOwned()) {
                            try {
                                var commPort: CommPort;
                                try {
                                    commPort = puerto.open(puerto.getName(), 2000);
                                    puertoAux = commPort as SerialPort;
                                    puertoAux.setSerialPortParams(500000, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                                    puertoAux.setInputBufferSize(2048);
                                    puertoAux.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
                                    puertoAux.notifyOnDataAvailable(true);
                                    puertoAux.notifyOnOutputEmpty(true);
                                    puertoAux.enableReceiveTimeout(2000);
                                    var input: InputStream = puertoAux.getInputStream();
                                    llegado = input.read();
                                    var salida: OutputStream = puertoAux.getOutputStream();
                                    salida.write(menviar, 0, 10);
                                    llegado = input.read();
                                    if (llegado > 0) {
                                        if (llegado == 250) {
                                            hayinterfaz = true;
                                            var nombre: String = puertoAux.getName();
                                            ////NO FUNCA!!! ARREGLAR
                                            nombre.replace('/', '');
                                            nombre.replace('.', '');
                                            ///////////////////////////////
                                            JOptionPane.showMessageDialog(null, "Conectado a interfaz eXtrae de puerto : {nombre}",
                                            "Operación Exitosa", JOptionPane.INFORMATION_MESSAGE);
                                            puertoAux.disableReceiveTimeout();
                                            //////Dejar el puertoSerial abierto con la configuraciÃ³n estÃ¡ndar
                                            puertoSerial = commPort as SerialPort;
                                            puertoSerial.setSerialPortParams(500000, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
                                            puertoSerial.setInputBufferSize(2048);
                                            puertoSerial.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
                                            puertoSerial.notifyOnDataAvailable(true);
                                            puertoSerial.notifyOnOutputEmpty(true);
                                            RecursoConectar = imageDesconectar;
                                            conectado = true;
                                        ////////////////////////////////////////////////////////////////
                                        }
                                    } else {
                                        commPort.close();
                                        puertoAux.close();
                                    }
                                } catch (e: Exception) {
                                    commPort.close();
                                    puertoAux.close();
                                }
                            } catch (e: Exception) {
                                JOptionPane.showMessageDialog(null, e, "Error", JOptionPane.INFORMATION_MESSAGE);
                            }

                        }
                    }
                }
                if (not conectado) {
                    JOptionPane.showMessageDialog(null, "No se ha detectado una interfaz eXtrae. Revisa las conexiones he intenta nuevamente.", "Error en la conexión", JOptionPane.INFORMATION_MESSAGE);
                }
            } catch (e: Exception) {
                JOptionPane.showMessageDialog(null, e, "Error en la conexión", JOptionPane.INFORMATION_MESSAGE);
            }
        }
    }

    function buttonAnalogoDigitalActionAtAnalogos(): Void {
        currentState.actual = currentState.findIndex("Digitales");
    }

    function buttonAnalogoDigitalActionAtDigitales(): Void {
        currentState.actual = currentState.findIndex("Analogos");
    }

    function botonInicioDigitalesActionAtInicio(): Void {
        currentState.actual = currentState.findIndex("Digitales");
    }

    function botonInicioAnalogosActionAtInicio(): Void {
        currentState.actual = currentState.findIndex("Analogos");
    }
    // </editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Timelines y otras creadas por Netbeans">

    public var dropShadowEffect: javafx.scene.effect.DropShadow = javafx.scene.effect.DropShadow {
            }
    public var innerShadowEffect: javafx.scene.effect.InnerShadow = javafx.scene.effect.InnerShadow {
            }
    public var scene: javafx.scene.Scene = javafx.scene.Scene {
                width: 800.0
                height: 600.0
                content: getDesignRootNodes()
                fill: null
                stylesheets: ["{__DIR__}Estilos.css",]
            }
    public var currentState: org.netbeans.javafx.design.DesignState = org.netbeans.javafx.design.DesignState {
                names: ["Digitales", "Analogos", "Inicio", "TiempoReal",]
                actual: 2
                timelines: [
                    //DIGITALES
                    javafx.animation.Timeline {
                        keyFrames: [
                            javafx.animation.KeyFrame {
                                time: 0ms
                                action: function() {
                                    recursoImagenAD = imagebotADA;
                                    botonInicioAnalogos.visible = false;
                                    botonInicioDigitales.visible = false;
                                    textboxNotas.visible = true;
                                    textboxNotas.layoutInfo = LayoutInfo { height: 206 width: 583.0 };
                                    textboxNotas.layoutX = 20;
                                    treeViewDatos.visible = true;
                                    imageLogo.visible = true;
                                    botonAbrir.visible = true;
                                    botonGuardar.visible = true;
                                    botonTiempoReal.visible = false;
                                    buttonAnalogoDigital.visible = true;
                                    buttonAnalogoDigital.effect = null;
                                    buttonAnalogoDigital.text = "";
                                    buttonAnalogoDigital.action = buttonAnalogoDigitalActionAtDigitales;
                                    botonConectar.visible = true;
                                    botonPlay.visible = true;
                                    panelCanalesAnalogos.visible = false;
                                    panelCanalesAnalogos.disable = false;
                                    panelInfoMedicion.visible = false;
                                    panelCanalesDigitales.visible = true;
                                    panelCanalesDigitales.disable = false;
                                    labelQueTipoUsar.visible = false;
                                    labelBienvenido.visible = false;
                                    imageViewLogoInicio.visible = false;
                                    progressbar.visible = false;
                                    botonEmergencia.visible = true;
                                    botonEmergencia.layoutY = 550.0;
                                    botonGuardarSerie.visible = false;
                                    checkBoxFlash.visible = false;
                                    buttonAnalogoDigital.layoutX = 690;
                                    osciloscopio.visible = false;
                                }
                            }
                        ]
                    }
                    //ANALOGOS
                    javafx.animation.Timeline {
                        keyFrames: [
                            javafx.animation.KeyFrame {
                                time: 0ms
                                action: function() {
                                    recursoImagenAD = imagebotADD;
                                    botonInicioAnalogos.visible = false;
                                    botonInicioDigitales.visible = false;
                                    textboxNotas.visible = true;
                                    textboxNotas.layoutX = 230.0;
                                    textboxNotas.layoutInfo = LayoutInfo { height: 206 width: 373.0 };
                                    treeViewDatos.visible = true;
                                    imageLogo.visible = true;
                                    botonAbrir.visible = true;
                                    botonGuardar.visible = true;
                                    botonTiempoReal.visible = true;
                                    buttonAnalogoDigital.visible = true;
                                    buttonAnalogoDigital.text = "";
                                    buttonAnalogoDigital.action = buttonAnalogoDigitalActionAtAnalogos;
                                    botonConectar.visible = true;
                                    botonPlay.visible = true;
                                    panelCanalesAnalogos.visible = true;
                                    panelCanalesAnalogos.disable = false;
                                    panelInfoMedicion.visible = true;
                                    panelCanalesDigitales.visible = false;
                                    panelCanalesDigitales.disable = true;
                                    labelQueTipoUsar.visible = false;
                                    labelBienvenido.visible = false;
                                    imageViewLogoInicio.visible = false;
                                    progressbar.visible = true;
                                    botonEmergencia.visible = true;
                                    botonEmergencia.layoutY = 570.0;
                                    labelNumeroDatosTitulo.visible = true;
                                    labelNumeroDatosInfo.visible = true;
                                    botonGuardarSerie.visible = false;
                                    checkBoxFlash.visible = false;
                                    buttonAnalogoDigital.layoutX = 690;
                                    osciloscopio.visible = false;
                                }
                            }
                        ]
                    }
                    //INICIO
                    javafx.animation.Timeline {
                        keyFrames: [
                            javafx.animation.KeyFrame {
                                time: 0ms
                                action: function() {
                                    recursoImagenAD = imagebotADA;
                                    botonInicioAnalogos.visible = true;
                                    botonInicioAnalogos.action = botonInicioAnalogosActionAtInicio;
                                    botonInicioDigitales.visible = true;
                                    botonInicioDigitales.action = botonInicioDigitalesActionAtInicio;
                                    textboxNotas.visible = false;
                                    textboxNotas.layoutX = 230.0;
                                    textboxNotas.width = 373.0;
                                    treeViewDatos.visible = false;
                                    imageLogo.visible = false;
                                    botonAbrir.visible = false;
                                    botonGuardar.visible = false;
                                    botonTiempoReal.visible = false;
                                    buttonAnalogoDigital.visible = false;
                                    buttonAnalogoDigital.text = "";
                                    botonConectar.visible = false;
                                    botonPlay.visible = false;
                                    panelCanalesAnalogos.visible = false;
                                    panelCanalesAnalogos.disable = false;
                                    panelInfoMedicion.visible = false;
                                    panelCanalesDigitales.visible = false;
                                    panelCanalesDigitales.disable = true;
                                    labelQueTipoUsar.visible = true;
                                    labelBienvenido.visible = true;
                                    imageViewLogoInicio.visible = true;
                                    progressbar.visible = false;
                                    botonEmergencia.visible = false;
                                    botonEmergencia.layoutY = 570.0;
                                    botonGuardarSerie.visible = false;
                                    checkBoxFlash.visible = false;
                                    buttonAnalogoDigital.layoutX = 690;
                                    osciloscopio.visible = false;
                                }
                            }
                        ]
                    }
                    //TIEMPO REAL
                    javafx.animation.Timeline {
                        keyFrames: [
                            javafx.animation.KeyFrame {
                                time: 0ms
                                action: function() {
                                    recursoImagenAD = imagebotADA;
                                    botonInicioAnalogos.visible = false;
                                    botonInicioDigitales.visible = false;
                                    textboxNotas.visible = false;
                                    textboxNotas.width = 583.0;
                                    textboxNotas.layoutX = 20;
                                    treeViewDatos.visible = false;
                                    imageLogo.visible = true;
                                    botonAbrir.visible = false;
                                    botonGuardar.visible = false;
                                    botonTiempoReal.visible = false;
                                    buttonAnalogoDigital.visible = true;
                                    buttonAnalogoDigital.effect = null;
                                    buttonAnalogoDigital.text = "";
                                    buttonAnalogoDigital.action = buttonAnalogoDigitalActionAtDigitales;
                                    botonConectar.visible = false;
                                    botonPlay.visible = true;
                                    panelCanalesAnalogos.visible = false;
                                    panelCanalesAnalogos.disable = false;
                                    panelInfoMedicion.visible = true;
                                    panelCanalesDigitales.visible = false;
                                    panelCanalesDigitales.disable = false;
                                    labelQueTipoUsar.visible = false;
                                    labelBienvenido.visible = false;
                                    imageViewLogoInicio.visible = false;
                                    progressbar.visible = false;
                                    botonEmergencia.visible = true;
                                    botonEmergencia.layoutY = 550.0;
                                    labelNumeroDatosTitulo.visible = false;
                                    labelNumeroDatosInfo.visible = false;
                                    botonGuardarSerie.visible = true;
                                    checkBoxFlash.visible = true;
                                    buttonAnalogoDigital.layoutX = 640;
                                    osciloscopio.visible = true;

                                }
                            }
                        ]
                    }
                ]
            }

    public function getDesignRootNodes(): javafx.scene.Node[] {
        [popupMenu, imageFondo, botonInicioAnalogos, botonInicioDigitales, textboxNotas,
            treeViewDatos, imageLogo, botonAbrir, botonGuardar,
            botonTiempoReal, buttonAnalogoDigital, botonConectar,
            botonPlay, panelCanalesAnalogos, panelInfoMedicion, panelCanalesDigitales,
            labelQueTipoUsar, labelBienvenido, imageViewLogoInicio, progressbar, botonEmergencia, botonGuardarSerie,
            checkBoxFlash, osciloscopio]
    }

    public function getDesignScene(): javafx.scene.Scene {
        scene
    }
    //</editor-fold>
    // <editor-fold defaultstate="collapsed" desc="Funciones: Graficar, generarTabla, poolSerial*,asignadorCanales y otras">
    function graficar(i: Integer, j: Integer, d: Integer): Void {
        if (d == 0) {
            var graf: Stage;
            var grafico: GraficoNode = GraficoNode {
                        Medicion: MedicionAnaloga {
                            Datos: MedicionesAN[i].Datos
                            parametros: MedicionesAN[i].parametros
                        } };
            grafico.addDatos(3, j, "Canal {j + 1} v/s t", 0);
            graf = Stage {
                        title: "Gráfico"
                        scene: Scene {
                            width: 600
                            height: 400
                            content: [grafico,] }
                    };
        } 
        else {
            var graf: Stage;
            var grafico: GraficoNode = GraficoNode {
                        MedicionDig: MedicionDigital {
                            Datos: MedicionesDIG[i].Datos
                            parametros: MedicionesDIG[i].parametros
                        } };
            grafico.addDatos(j, j, "Canal Digital {j + 1} v/s t", 1);
            graf = Stage {
                        title: "Gráfico"
                        scene: Scene {
                            width: 600
                            height: 400
                            content: [grafico,] }
                    };
            if(MedicionesDIG[i].parametros.canalSensor[j].tipoInterrupcion){
            var graf2: Stage;
            var grafico2: GraficoNode = GraficoNode {
                        MedicionDig: MedicionDigital {
                            Datos: MedicionesDIG[i].Datos
                            parametros: MedicionesDIG[i].parametros
                        } };
            grafico2.addDatos(j, j, "Canal Digital {j + 1} v/s t", 2);
            graf2 = Stage {
                        title: "Gráfico"
                        scene: Scene {
                            width: 600
                            height: 400
                            content: [grafico2,] }
                    };}
        }
    }
    function generarTabla(i:Integer,j:Integer,d:Integer):Void{
        if (d == 0) {
            var tab: Stage;
            var tabla: Tabla =Tabla {};
            tabla.addDatos(MedicionesAN[i]);
            tab = Stage {
                        title: "Tabla"
                        scene: Scene {
                            width: 550
                            height: 600
                            content: [tabla,] }
                    };
        }
        else {
            var tab: Stage;
            var tabla: Tabla =Tabla {};
            tabla.addDatos(MedicionesDIG[i],0);
            tab = Stage {
                        title: "Tabla"
                        scene: Scene {
                            width: 550
                            height: 600
                            content: [tabla,] }
                    };
            var tab2: Stage;
            var tabla2: Tabla =Tabla {};
            tabla2.addDatos(MedicionesDIG[i],1);
            tab2 = Stage {
                        title: "Tabla"
                        scene: Scene {
                            width: 550
                            height: 600
                            content: [tabla2,] }
                    };
            var tab3: Stage;
            var tabla3: Tabla =Tabla {};
            tabla3.addDatos(MedicionesDIG[i],2);
            tab3 = Stage {
                        title: "Tabla"
                        scene: Scene {
                            width: 550
                            height: 600
                            content: [tabla3,] }
                    };
        }
        };
    public function unidadesPalabra(unid: Integer): String {
        if (unid == 0) {
            return "[us]";
        } else if (unid == 1) {
            return "[ms]";
        } else if (unid == 2) {
            return "[s]";
        } else if (unid == 3) {
            return "[m]";
        } else if (unid == 4) {
            return "[h]";
        } else if (unid == 5) {
            return "[d]";
        } else return "";
    }
    public function poolserial(): Void {
        var input: InputStream = puertoSerial.getInputStream();
        var data: Byte[];
        var valor: Integer[];
        while (input.available() > 3 and recibiendo) {
            for (l in [0..3]) {
                data[l] = input.read(); }
            valor[0] = (Bits.bitAnd(Bits.shiftLeft(data[0], 2), 1020)) + Bits.shiftRight(data[1], 6);
            valor[1] = (Bits.bitAnd(Bits.shiftLeft(data[1], 4), 1008)) + Bits.shiftRight(data[2], 4);
            valor[2] = (Bits.bitAnd(Bits.shiftLeft(data[2], 6), 960)) + Bits.shiftRight(data[3], 2);
            for (n in [0..2]) {
                if (paramAN.canalActivo[n]) {
                    (StagesAN[n].StageANTabla[timingANA[n] - 1].scene.content[0] as TablaLlegadaDatos).addData(counterRecibidosAN * paramAN.valorTasa, (valor[n] * paramAN.canalSensor[n].pendiente + paramAN.canalSensor[n].corte));
                    (StagesAN[n].StageANGrafico[timingANA[n] - 1].scene.content[0] as GraficoLlegadaDatos).addData((counterRecibidosAN * 450 / paramAN.numeroDatos), (-valor[n] * 280 / 1024));
                    insert (valor[n] * paramAN.canalSensor[n].pendiente + paramAN.canalSensor[n].corte) into MedicionesAN[timingAN - 1].Datos[n].Datos;
                }
            }
            insert counterRecibidosAN * paramAN.valorTasa into MedicionesAN[timingAN - 1].Datos[3].Datos;
            counterRecibidosAN++;
            if (counterRecibidosAN == paramAN.numeroDatos) {
                botonPlay.text = "Comenzar";
                counterRecibidosAN = 0;
                recibiendo = false;
                timerPooling.stop();
            }

        }//While
    }
    public function poolserialOsciloscopio(): Void {
        var input: InputStream = puertoSerial.getInputStream();
        var data: Byte[];
        var valor: Integer[];
        while (input.available() > 3 and recibiendo) {
            for (l in [0..3]) {
                data[l] = input.read(); }
            valor[0] = (Bits.bitAnd(Bits.shiftLeft(data[0], 2), 1020)) + Bits.shiftRight(data[1], 6);
            valor[1] = (Bits.bitAnd(Bits.shiftLeft(data[1], 4), 1008)) + Bits.shiftRight(data[2], 4);
            valor[2] = (Bits.bitAnd(Bits.shiftLeft(data[2], 6), 960)) + Bits.shiftRight(data[3], 2);
            osciloscopio.addDato(paramAN.canalActivo, valor, paramAN.valorTasa);

            //Se envian los tres Datos , falta arreglar el flash de ejemplo//
            if (not (servidorXML.socketConnection == null) and (not socketClosed)) {
                try {
                    servidorXML.sendMessage("<?xml version=\"1.0\" encoding=\"UTF-8\"?><dato>{valor[0]}</dato>");
                }
                catch (e: Exception) {

                }
            }
        }//While
    }
    public function poolserialDigital(): Void {
        var input: InputStream = puertoSerial.getInputStream();
        var data: Integer[];
        var valor: Double;
        while (input.available() > 4 and recibiendo) {

            for (l in [0..4]) {
                data[l] = input.read(); }
            valor = Bits.shiftLeft(data[1], 24) + Bits.shiftLeft(data[2], 16)
                    + Bits.shiftLeft(data[3], 8) + Bits.shiftLeft(data[4], 0);
            var n: Integer = data[0] - 1;

            if (paramDIG.canalActivo[n]) {
                (StagesDIG[n].StageDIGTabla[timingDIGI[n] - 1].scene.content[0] as TablaLlegadaDatos).addData(counterRecibidosDIG[n], valor / 1000000);
                insert (valor) into MedicionesDIG[timingDIG - 1].Datos[n].Datos;
                if (paramDIG.canalSensor[n].tipoInterrupcion) {
                    if (counterVel[n] > 0) {
                        var vel = ((paramDIG.canalSensor[n].regleta)) / ((valor - MedicionesDIG[timingDIG - 1].Datos[n].Datos[MedicionesDIG[timingDIG - 1].Datos[n].Datos.size() - 2]) / 1000);
                        var tiempo = (valor + MedicionesDIG[timingDIG - 1].Datos[n].Datos[MedicionesDIG[timingDIG - 1].Datos[n].Datos.size() - 2]) / 2000000;
                        (StagesDIGVel[n].StageDIGTabla[timingDIGI[n] - 1].scene.content[0] as TablaLlegadaDatos).addData(vel, tiempo);
                    }
                } else {
                    if (counterVel[n] == 1) {
                        var vel = ((paramDIG.canalSensor[n].regleta)) / ((valor - MedicionesDIG[timingDIG - 1].Datos[n].Datos[MedicionesDIG[timingDIG - 1].Datos[n].Datos.size() - 2]) / 1000);
                        var tiempo = (valor + MedicionesDIG[timingDIG - 1].Datos[n].Datos[MedicionesDIG[timingDIG - 1].Datos[n].Datos.size() - 2]) / 2000000;
                        (StagesDIGVel[n].StageDIGTabla[timingDIGI[n] - 1].scene.content[0] as TablaLlegadaDatos).addData(vel, tiempo);
                        counterVel[n] = -1;
                    }

                }
                counterRecibidosDIG[n]++;
                counterVel[n]++;
            }
        //insert counterRecibidosAN * paramAN.valorTasa into MedicionesAN[timingAN - 1].Datos[3].Datos;
        }//While
    }

    public function asignadorCanal(tipo: Integer, canal: Integer): function() {
        if (tipo == 0) { //ANALOGO
            return (function(): Void {
                        var selector: selectorSensores;
                        var sensorElegido: sensorNodeAN = sensorNodeAN {};
                        var nodos: Node[];// = selector2.SENSORES_INFO_AN;
                        for (n in selector.SENSORES_INFO_AN) { insert n into nodos; }
                        var numselec: Integer = 0;
                        for (nod in nodos) {
                            nod.effect = null;
                            nod.onMouseClicked = function(event): Void {
                                        for (ned in nodos) {
                                            if (ned == sensorElegido) {
                                                ned.effect = null;
                                                numselec--;
                                            }
                                        }
                                        sensorElegido = (nod as sensorNodeAN);
                                        nod.effect = dropShadowEffect;
                                        numselec++;
                                    } }
                        var guardar:Boolean=false;

                        var dialogo: XDialog = XDialog {
                                    resizable: true
                                    modal: false
                                    width:410
                                    height:400
                                    scene: Scene {
                                        width: 410
                                        height: 400
                                        content: [ScrollView {width:bind (dialogo.scene.width)
                                                                    height:bind (dialogo.scene.height-35)
                                                                    node:VBox {spacing:10.0 content: [nodos]}},
                                                                HBox{height:20 width:bind (dialogo.scene.width) layoutY:bind (dialogo.scene.height-25) hpos:HPos.CENTER spacing:20.0 content:[
                                                                    Button{text:"Seleccionar" action:function():Void{guardar=true;dialogo.close();}},
                                                                    Button{text:"Cancelar" action:function():Void{guardar=false;dialogo.close();}} ]} ]
                                                        }
                                    onClose: function(): Void {
                                        if (numselec == 1 and guardar) {
                                            paramAN.canalSensor[canal] = sensorElegido.hacer();
                                            canalesAN[canal].checkboxAN.selected = true;
                                        }
                                    }
                                };
                    });
        }
        else {//DIGITALES
            return (function(): Void {
                        var selector: selectorSensores;
                        var sensorElegido: sensorNode = sensorNode {};
                        var nodos: Node[];
                        for (n in selector.SENSORES_INFO) { insert n into nodos; }
                        var numselec: Integer = 0;
                        for (nod in nodos) {
                            nod.effect = null;
                            nod.onMouseClicked = function(event): Void {
                                        for (ned in nodos) {
                                            if (ned == sensorElegido) {
                                                ned.effect = null;
                                                numselec--;
                                            }
                                        }
                                        sensorElegido = (nod as sensorNode);
                                        nod.effect = dropShadowEffect;
                                        numselec++;
                                    } }
                        var guardar:Boolean=false;
                        var dialogo: XDialog = XDialog {
                                    resizable: true
                                    modal: false
                                    width:410
                                    height:400
                                    scene: Scene {
                                        width: 410
                                        height: 400
                                        content: [ScrollView {width:bind (dialogo.scene.width)
                                                                    height:bind (dialogo.scene.height-35)
                                                                    node:VBox {spacing:10.0 content: [nodos]}},
                                                                HBox{height:20 width:bind (dialogo.scene.width) layoutY:bind (dialogo.scene.height-25) hpos:HPos.CENTER spacing:20.0 content:[
                                                                    Button{text:"Seleccionar" action:function():Void{guardar=true;dialogo.close();}},
                                                                    Button{text:"Cancelar" action:function():Void{guardar=false;dialogo.close();}} ]} ]
                                                        }
                                    onClose: function(): Void {
                                        if (numselec == 1 and guardar) {
                                            paramDIG.canalSensor[canal] = sensorElegido.hacer();
                                            canalesDIG[canal].checkboxDIG.selected = true;
                                        }
                                    }
                                };
                    });
        }

    }
    //</editor-fold>
}

public class ServerSocketListener extends SocketListener {

    public override function onMessage(line: String) {
        JOptionPane.showMessageDialog(null, line, "", JOptionPane.INFORMATION_MESSAGE);
    }

    public override function onClosedStatus(isClosed: java.lang.Boolean) {
    }

}

function run(): Void {
    var design = Main {};
    javafx.stage.Stage {
        title: "Interfaz de Usuario"
        scene: design.getDesignScene()
    }
}
